package com.scwatch.ext.service.impl;

import com.scwatch.common.orm.SearchFilter;
import com.scwatch.ext.domain.ScheduleJob;
import com.scwatch.ext.repository.ScheduleJobDao;
import com.scwatch.ext.service.ScheduleJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Service
@Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
public class ScheduleJobServiceImpl implements ScheduleJobService {

    @Autowired
    private ScheduleJobDao dao;


    @Override
    public Page<ScheduleJob> findAll(Integer siteId, Map<String, String[]> params, Pageable pageable) {
        return dao.findAll(spec(siteId,params),pageable);
    }

    @Transactional
    public void deleteByPrimaryKey(Integer[] ids) {
        for (Integer jobId : ids) {
            ScheduleJob scheduleJob = selectByPrimaryKey(jobId);
            dao.delete(scheduleJob);
        }
    }

    @Transactional
    public ScheduleJob insert(ScheduleJob record) {
        return dao.save(record);
    }

    @Transactional
    public ScheduleJob insertSelective(ScheduleJob record) {
        return dao.save(record);
    }

    @Override
    public List<ScheduleJob> finByNameAndGroup(String jobName, String jobGroup) {
        return dao.finByNameAndGroup(jobName, jobGroup);
    }

    @Override
    public List<ScheduleJob> finByClassAndMethod(String beanClass, String methodName) {
        return dao.finByClassAndMethod(beanClass, methodName);
    }



    @Override
    public ScheduleJob selectByPrimaryKey(Integer jobId) {
        return dao.findOne(jobId);
    }

    @Transactional
    public ScheduleJob updateByPrimaryKeySelective(ScheduleJob record) {
        return dao.save(record);
    }

    @Transactional
    public ScheduleJob updateByPrimaryKey(ScheduleJob record) {
        return dao.save(record);
    }

    @Override
    public List<ScheduleJob> getAll(Integer siteId) {
        return dao.findAllByState(siteId);
    }

    @Override
    public List<ScheduleJob> getAll() {
        return dao.findAllByState();
    }

    @Override
    public List<ScheduleJob> findByjobName(String jobName) {
        return dao.findByjobName(jobName);
    }

    private Specification<ScheduleJob> spec(final Integer siteId, Map<String, String[]> params) {
        Collection<SearchFilter> filters = SearchFilter.parse(params).values();
        final Specification<ScheduleJob> fsp = SearchFilter.spec(filters, ScheduleJob.class);
        Specification<ScheduleJob> sp = new Specification<ScheduleJob>() {
            public Predicate toPredicate(Root<ScheduleJob> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate pred = fsp.toPredicate(root, query, cb);
                if (siteId != null) {
                    pred = cb.and(pred, cb.equal(root.get("site").<Integer>get("id"), siteId));
                }
                return pred;
            }
        };
        return sp;
    }
}
